<script setup>
    import {ref,reactive,computed,h, onMounted, nextTick} from 'vue';
    import io from 'socket.io-client';
    import $ from 'jquery'
    import  showdown from 'showdown';

    import {_dateTimeFormatter} from "../utils/dateutil.js"

   const baseBackEndServerUrl = "http://localhost:3000";
   const baseFrontEndServerUrl = "http://localhost:5173";
    var markdown = ref("");
    var convertedMarkdown = computed(()=>{
        const converter = new showdown.Converter();
        return converter.makeHtml(markdown.value);
    }); 

    /**
     * 所有的消息列表，格式：
     * { type: system || talk ,content:"xxxx" , time: "2023-01-01 15:23" , from: "username" , to:"username"} // 群发的时候to=all
     * 
     */
    var messageList = reactive([])
    // 做一个测试数据
    // messageList = [
    //     {type: "system" ,content:"123加入了群聊" , time: "2023-01-01 15:23" , from: "123" ,fromavatar:"http://localhost:5173/assets/images/avatar01.jpg", to:"all"},
    //     {type: "talk" ,content:"你好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar02.jpg", to:"all"},
    //     {type: "talk" ,content:"你也好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar03.jpg", to:"all"},
    //     {type: "system" ,content:"456离开了了群聊" , time: "2023-01-01 16:13" , from: "456",fromavatar:"http://localhost:5173/assets/images/avatar04.jpg" , to:"all"},
    //     {type: "talk" ,content:"大家好才是真的好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar05.jpg", to:"all"},
    //     {type: "talk" ,content:"大家好才是真的好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar05.jpg", to:"all"},
    //     {type: "talk" ,content:"大家好才是真的好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar05.jpg", to:"all"},
    //     {type: "talk" ,content:"大家好才是真的好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar05.jpg", to:"all"},
    //     {type: "talk" ,content:"大家好才是真的好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar05.jpg", to:"all"},
    //     {type: "talk" ,content:"大家好才是真的好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar05.jpg", to:"all"},
    //     {type: "talk" ,content:"大家好才是真的好" , time: "2023-01-01 15:23" , from: "srx" ,fromavatar:"http://localhost:5173/assets/images/avatar05.jpg", to:"all"},

    // ];

    function creatMsg(type,contentType,content,from,avata,to){
        messageList.push( {type:type,contentType:contentType,content:content,time:_dateTimeFormatter(new Date()),from:from,fromavatar:avata,to:to})
    }
    function createSystemMsg(content,from,avata){
        creatMsg("system","text",content,from,avata,"all")
    }
    function createTalkMsg(content,from,avata,to){
        creatMsg("talk","text",content,from,avata,to)
    }
    function createImageMsg(content,from,avata,to){
        creatMsg("talk","image",content,from,avata,"all")
    }

    var socket =io(baseBackEndServerUrl)

    /**
     * 前端连接服务器
     */
    socket.on('connect',()=>{
        console.log("Connected to server");
    })
   
    /**
     * 前端动画
     */
    // imgs class 10个图
    var userAvata = ref(baseFrontEndServerUrl+"/assets/images/avatar01.jpg");
    var sessionUserAvata = sessionStorage.getItem("userAvata");
    if(sessionUserAvata!=null && sessionUserAvata!="null" && sessionUserAvata!=""){
        userAvata.value = sessionUserAvata
    }

    const setImgPickedUp = function(e){
        console.log(e.target);
        var dom = e.target;
         
         $(".avatar li").removeClass(); // jquery 设置样式还是很方便。
         dom.parentNode.className = "now";
         userAvata.value = dom.src; // H5
         console.log(userAvata.value );
    }


    var showLogin = ref(true);
   

    /**
     * 从本地存储里取username
     */
    var sessionUsername = sessionStorage.getItem('username');
    console.log("sessionUsername="+sessionUsername);
    var username = ref(sessionUsername);
    // debugger
    if(sessionUsername ==null || 
       sessionUsername =="" || 
       sessionUsername =="null" || 
       sessionUsername==undefined){
        console.log("set showlogin = true");
        showLogin.value = true;
    }else{
        console.log("set showlogin = false");
        showLogin.value = false;
    }

    console.log("showLogin.value ="+showLogin.value );


    /**
     * 从本地存储里取userList.
     */
    var userList = ref([])
    // var sessionUserList = sessionStorage.getItem('userList')
    var sessionUserList = JSON.parse(sessionStorage.getItem('userList'));
    console.log("sessionUserList=",sessionUserList);
    if(sessionUserList!=null && sessionUserList.length>0){
        sessionUserList.forEach(user=>{
            console.log(user.username,user.avata);
        })
        userList.value = sessionUserList;
    }
    


    var userCount = computed(()=>{
        if(userList.value == null ){
            return 0;
        }else{
            return userList.value.length;
        }
    })
    
    /**
     * 前端发送login请求
     */
    const loginHandler = function(){
        if(username.value ==null){
            alert("error: username is required!")
            return ;
        }
        console.log(username.value,userAvata.value);
        socket.emit("login",{"username":username.value,"avata":userAvata.value})
    }
    var message = ref("")
    
 
    

    

    /**
     * 前端处理login成功
     */
    socket.on("loginSuccess",(_userList)=>{ // {username,avata}
        console.log("loginSuccess __userList=",_userList);
        showLogin.value = false; // 就不用显示login画面了。但是一刷新就重置了。怎么办？
        userList.value = _userList;
        console.log("loginSuccess 客户端接收到最新的用户列表：userList.value=",userList.value);

        sessionStorage.setItem('username', username.value);
        sessionStorage.setItem('userAvata',userAvata.value);
        sessionStorage.setItem('userList', JSON.stringify(userList.value));
       
        // 消息列表
        createSystemMsg(username.value+"加入了群聊",username.value,userAvata.value);
    })

    /**
     * 显示哪个用户已经登陆。
     */
    var newUser = ref(null)
    socket.on("userListChanged",({"userList":_userList,"newUser":_newUser})=>{
        userList.value = _userList;
        console.log("userListChanged 客户端接收到最新的用户列表：userList.value=",userList.value,"newUser:",_newUser);
        sessionStorage.setItem('userList', JSON.stringify(userList.value));
        newUser.value = _newUser.username; // 欢迎新用户
        //addUser(_newUser.username); // css无效
         // 消息列表
         createSystemMsg(username.value+"加入了群聊",username.value,userAvata.value);
    })

    /**
     * 前端处理重复登录
     */
    var serverUserList =[]
    var serverUserName = ""
    socket.on("noneed2login",(data)=>{
        // console.log("noneed2login",serverUserList,userObj);
        console.log("no need to login. data===>",data);
        message.value = "已经登陆过了。"
        userList.value = data.userList;
        username.value = data.data.username;
        userAvata.value = data.data.avata;
        sessionStorage.setItem('username', username.value);
        sessionStorage.setItem('userAvata',userAvata.value);
        sessionStorage.setItem('userList', JSON.stringify(userList.value));

        showLogin.value = false;
    })
    


    /**
     * 前端关闭浏览器时，清除session
     */
    socket.on('disconnect', () => {
        // 删除存储在sessionStorage中的数据
        sessionStorage.removeItem('username');
        sessionStorage.removeItem('userList');

        // 清空sessionStorage中的所有数据
        //sessionStorage.clear();
        console.log('Disconnected from server');
    });

    /**
     * 有人退出，处理服务器群发推送的消息。
     */
    socket.on("someoneDisconnect",(_userList)=>{
        userList.value = _userList;
        console.log("someoneDisconnect 客户端接收到最新的用户列表：userList.value=",userList.value);

        sessionStorage.setItem('username', username.value);
        sessionStorage.setItem('userAvata',userAvata.value);
        sessionStorage.setItem('userList', JSON.stringify(userList.value));

         // 消息列表
         createSystemMsg(username.value+"退出了群聊",username.value,userAvata.value);
    })
   
    /**
     * 发普通文本
     */
    var textarea =ref("")
    const sendMsg = function(){
        
        if(markdown.value == "" || markdown.value ==""){
            return;
        }
        var obj = {type:"talk",content:markdown.value,from:username.value,fromavata:userAvata.value,to:"all"} // 暂定群聊
        socket.emit("sendMsgToServer",obj)
        markdown.value = "";

        // if(textarea.value.textContent ==""){
        //     return ;
        // }
        // var obj = {type:"talk",content:textarea.value.textContent,from:username.value,fromavata:userAvata.value,to:"all"} // 暂定群聊
        // socket.emit("sendMsgToServer",obj)
        
        // textarea.value.innerHTML = "";
        // console.log("textarea.value.innerHTML",textarea.value.innerHTML);
        
    }

    /**
     * receive others text message
     */
    // 接广播消息。
    socket.on("broadcaseMsgToClients",obj=>{
        //broadcaseMsgToClients
        //{type:"talk",content:textarea.value.textContent,from:username.value,to:"all"} // 暂定群聊


       //createTalkMsg(obj.content,obj.from,obj.fromavata)

        var converter = new showdown.Converter(),
       // text      = '# hello, markdown!',
        html      = converter.makeHtml(obj.content);
        createTalkMsg(html,obj.from,obj.fromavata);

       
     nextTick(()=>{
        var msgBoxes = document.getElementsByClassName("box-bd");
       
        var target = msgBoxes[msgBoxes.length - 1];
     //   console.log("msgBoxes===>",msgBoxes,"target==>",target," target.offsetTop==>",target.offsetTop);
       // $(target).animate({"scrollBottom": $(target).offset().top() }, 'normal');
        // target.scrollTo(0, target.offsetTop);
        target.scrollTop = target.scrollHeight;
     })
       
        

    })

    /**
     * 发小图OK。大图自动断连接（NG）
     * 
     */
    var htmlImgFile = ref(null);
    const sendImg = function(e){
        const selectedFile = e.target.files[0];
        var fr = new FileReader();
        
        fr.onloadend = function(ev){
            console.log("sendImage ev.target.result",ev.target.result);
            //fr.result在控制台输出Base64编码的字符串
            var obj = {type:"image",content:fr.result,from:username.value,fromavata:userAvata.value,to:"all"} // 暂定群聊
            socket.emit("sendImage",obj);
        }

        if (selectedFile && selectedFile.type.match('image.*')) {
            fr.readAsDataURL(selectedFile)
        }else{
            console.log("error：selectedFile 类型不对！！");
        }
    }

    /**
     * receive others image message
     */
    socket.on("broadcaseImageToClients",obj=>{
        // {
        //         usernama:username.value,
        //         avata: userAvata.value,
        //         img : fr.result
        //     })
        console.log("broadcaseImageToClients ",obj);
        createImageMsg(obj.content,obj.from,obj.fromavata,obj.to);
    })


    //从服务器上获得大图
    const getBigImage = function(){
        socket.emit("getBigImage");
    }

    var imgChunks = [];
    socket.on("img-chunk",chunk=>{
        var srx = document.getElementById("srx");
        imgChunks.push(chunk);
        srx.setAttribute("src","data:image/jpeg;base64,"+window.btoa(imgChunks));
    })

    /**
     * 发送按钮 ctrl+Enter
     * @param {} event 
     */
    function handleKeyDown(event) {
    //   console.log("event.keyCode=>>>>>",event.keyCode);
       if (event.ctrlKey && event.keyCode === 13) {
        // 执行发送内容的操作

        sendMsg();
      }
    }

    // //滚动条触发事件
    // function scrollEvent(e) {
    //     // console.log(e)
    //     if (e.srcElement.scrollTop + e.srcElement.clientHeight >= e.srcElement.scrollHeight ) {
    //         console.log("嘿嘿我在底部触发了")
    //     }
    // }

    var markdownPreview = ref(false)
    const togglePreview = function(){
        markdownPreview.value = !markdownPreview.value;
    }
</script>

<template>
    <div class="loginPage">
        <!-- 注册部分 -->
        <div class="register-box" style="display: none;">
        </div>


        <!-- 登陆部分 -->
        <div class="login_box" v-if="showLogin" style="display: block;">
            <h3>用户登录</h3>
            <p>用户名</p>
            <input type="text" placeholder="请输入用户名" id="username" v-model="username"/>
            <p>选择头像</p>
            <ul class="avatar" id="login_avatar">
                
                <li class="now"><img src="/assets/images/avatar01.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar02.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar03.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar04.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar05.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar06.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar07.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar08.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar09.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
                <li><img src="/assets/images/avatar10.jpg" @click= "setImgPickedUp($event)" alt="" /></li>
            </ul>
            <button class="weui-btn" id="loginBtn" @click="loginHandler()">登录</button>
        </div>


        <!-- 聊天室部分 -->
        <div class="container"  v-if="!showLogin">
                <!-- 用户列表 -->
                <div class="user-list">
                    <div class="header">
                    <div class="avatar">
                        <img class="img avatar_url" :src="userAvata" alt="" />
                    </div>
                    <div class="info">
                        <!--  -->
                        <h3 class="username">{{username}}</h3>
                    </div>
                    </div>
                    <div class="title"><h3>用户列表</h3></div>
                    <ul>
            
                    <li class="user" v-for="usr in userList">
                        <div class="avatar"><img :src="usr.avata" alt="" /></div>
                        <div class="name">{{ usr.username }}</div>
                    </li> 
            
                    </ul>
                </div>
                <!-- 聊天主窗口 -->
                <div class="box">
                    <!-- 聊天窗口头部 -->
                    <div class="box-hd"><h3>聊天室(<span id="userCount">{{userCount}}</span>)</h3></div>

                    <!-- 聊天窗口主体区域 -->
                    <div ref="chatBox" id="chatBox" class="box-bd" >
                        
                        <div v-for="(msg,index) in messageList">
                            <Transition>
                            <div  v-if="msg.type=='system'" class="system">
                                <p class="message_system">
                                      <span class="content">{{msg.content}}加入了群聊</span>
                                </p>
                            </div>
                       
                            <div v-else-if="msg.type=='talk' && msg.from==username" class="message-box">
                                <div class="my message">
                                    <img class="avatar" :src="msg.fromavatar" alt="" />
                                    <div class="content">
                                        <div class="bubble">
                                           
                                            <div v-if="msg.contentType=='text'" class="bubble_cont">
                                                <span v-html="msg.content"></span> 
                                            </div>
                                            <div v-if="msg.contentType=='image'" class="bubble_cont">
                                                <img :src="msg.content" alt="ended pic">
                                            </div>
                                           
                                        </div>
                                    </div>
                                    <div   class="system">
                                                <p class="message_system">
                                                    <span class="content">{{msg.time}}</span>
                                                </p>
                                      </div>
                                </div>
                            </div>
                            <div v-else-if="msg.type=='talk' && msg.from!=username" class="message-box">
                                <div class="other message">
                                    <img class="avatar" :src="msg.fromavatar"  alt="" />
                                    <div class="content">
                                        <div class="nickname">{{msg.from}}</div>
                                        <div class="bubble">
                                            
                                            <div v-if="msg.contentType=='text'" class="bubble_cont">
                                                <span v-html="msg.content"></span> 
                                            </div>
                                            <div v-if="msg.contentType=='image'" class="bubble_cont">
                                                <img :src="msg.content" alt="ended pic">
                                            </div>
                                            
                                        </div>
                                    </div>
                                    <div   class="system">
                                                <p class="message_system">
                                                    <span class="content">{{msg.time}}</span>
                                                </p>
                                    </div>
                                </div>
                            </div>
                        </Transition>

                        <img id="srx" src="" alt="">
                       
                        </div>   
                    </div>
                     <!-- <teleport to="chatBox"> -->
                        <div class="popup" v-if="markdownPreview==true">
                             <div v-html="convertedMarkdown" class="popup-inner"></div>
                           </div>
                        <!-- </teleport> -->
                    <!-- 聊天窗口底部区域 -->
                    <div class="box-ft">
                    <!-- 工具栏 -->
                    <div class="toolbar">
                         <a href="javascript:;" title="表情" >
                            <font-awesome-icon :icon="['fass', 'face-smile']" />
                         </a> 
                        
                        <a href="javascript:;" title="截屏" >
                            <font-awesome-icon :icon="['fa', 'scissors']" />
                        </a> 
                        <font-awesome-icon :icon="['fa', 'folder-open']" >
                            <a href="javascript:;" title="图片" class="file">
                                <label for="file"></label>
                                <input type="file" id="file" ref="htmlImgFile" @change="sendImg($event)"  style="display: none;">
                                
                            </a>
                        </font-awesome-icon>
                        <a href="javascript:;" title="mdPreview"  @click="togglePreview()">
                            <font-awesome-icon icon="fa fa-play" />
                        </a>

                    </div>
                    <!-- 内容输入区域 -->
                    <div class="content">
                        <!-- div添加一个属性：contenteditable 可编辑div文本内容-->
                        <textarea v-model="markdown" class="text" @keydown="handleKeyDown($event)"></textarea>
                    </div>
                    <!-- 发送按钮 -->
                    <div class="action">
                        <span class="desc">按下Ctrl+Enter发送</span>
                        <!-- 给a标签加一个空js，消除a默认的返回顶部效果 -->
                        
                        <a class="btn-send" id="btn-send" href="javascript:;"  @click="sendMsg">发送</a>
                        <a class="btn-send" id="btn-send" href="javascript:;" @click="getBigImage">获得大图</a>
                    </div>
                    </div>
                </div>
        </div>
    </div>
   
</template>


<style scoped>
    @import url(../assets/css/index.css);
    .loginPage{
        height: 100vh;
        width:100vw;
        background: url('../assets/images/bg.jpg') no-repeat center center;
    }

    /* .container{
        transition:  all 3000ms ease-in;
    } */
/*  不生效
    .v-enter-active,
    .v-leave-active {
    transition: opacity 2s ease;
    }

    .v-enter-from,
    .v-leave-to {
    opacity: 0;
    } */

    .popup {
        position: fixed;
        top: 100px;
        bottom: 200px;
        left: 500px;
        right: 200px; 
        /* width:300px;
        height:300px; */
        z-index: 99;
        background: rgba(0, 0, 0, 0.1);
        display: flex;
        /* justify-content: center;
        align-items: center; */
        /* border: 1px solid blue; */
    }

    .popup-inner {
        /* background:  rgba(0, 0, 0, 0.1); */
        /* position: relative; */
        padding: 32px;
        /* border: 1px solid black; */
    }

   
</style>